package com.springapi.utils;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.UUID;
@Component
public class TokenUtil {

    // 密钥（请确保在生产环境中使用安全的密钥，并避免硬编码在代码中）
    private static final String SECRET_KEY = "abcdefgabcdefghijklmnopqrstuvwxyz"; // 请替换为实际的密钥
    // Token过期时间（毫秒），5个小时
    private static final long TOKEN_EXPIRATION_TIME_MS = 12 * 60 * 60 * 1000L;
    //private static final long TOKEN_EXPIRATION_TIME_MS = 60 * 1000L;
    // 生成Token
    public static String generateToken() {
        String uuid = UUID.randomUUID().toString();
        long timestamp = System.currentTimeMillis();
        long expirationTimestamp = timestamp + TOKEN_EXPIRATION_TIME_MS;

        // 对UUID和过期时间戳进行签名
        String dataToSign = uuid + "." + expirationTimestamp;
        String tokenSignature = hmacSha256Hex(SECRET_KEY, dataToSign);

        // 返回的格式为：UUID.过期时间戳.签名
        return uuid + "." + expirationTimestamp + "." + tokenSignature;
    }

    // 验证Token
    public static boolean validateToken(String token) {
        if (token == null || !token.contains(".")) {
            return false;
        }

        String[] parts = token.split("\\.");
        if (parts.length != 3) {
            return false;
        }

        String uuid = parts[0];
        long expirationTimestamp;
        try {
            expirationTimestamp = Long.parseLong(parts[1]);
        } catch (NumberFormatException e) {
            return false;
        }
        String tokenSignature = parts[2];

        // 检查是否过期
        long currentTime = System.currentTimeMillis();
        if (currentTime > expirationTimestamp) {
            return false;
        }

        // 计算签名并验证
        String dataToSign = uuid + "." + expirationTimestamp;
        String calculatedSignature = hmacSha256Hex(SECRET_KEY, dataToSign);

        return tokenSignature.equals(calculatedSignature);
    }

    // 使用HMAC-SHA256算法生成签名（与之前相同）
    private static String hmacSha256Hex(String key, String data) {
        try {
            Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
            SecretKeySpec secret_key = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
            sha256_HMAC.init(secret_key);

            byte[] hash = sha256_HMAC.doFinal(data.getBytes(StandardCharsets.UTF_8));
            // 这里使用Hex编码而不是Base64，因为Hex编码的字符串更容易在URL和token中传递
            return bytesToHex(hash);
        } catch (NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to generate HMAC-SHA256 signature", e);
        }
    }

    // 辅助方法：将字节数组转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }

    // 测试方法（与之前相同，但用于测试新的过期逻辑）
    public static void main(String[] args) {
        String token = generateToken();
        System.out.println("Generated Token: " + token);

        // 等待一段时间（例如1分钟），然后验证token
        try {
            Thread.sleep(1 * 60 * 1000L); // 1分钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        boolean isValid = validateToken(token);
        System.out.println("Is Token Valid after 1 minute: " + isValid);

        // 再次等待超过剩余过期时间（例如4小时59分钟），然后验证token
        try {
            Thread.sleep(4 * 60 * 60 * 1000L + 59 * 60 * 1000L); // 4小时59分钟
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        isValid = validateToken(token);
        System.out.println("Is Token Valid after 5 hours: " + isValid);
    }
}